// MPW TypeScript 类型定义

export type PasswordTemplate =
  | 'maximum'
  | 'long'
  | 'medium'
  | 'basic'
  | 'short'
  | 'pin'
  | 'name'
  | 'phrase';

export type HashAlgorithm = 'SHA-1' | 'SHA-224' | 'SHA-256' | 'SHA-384' | 'SHA-512';

export interface MPWTemplates {
  maximum: string[];
  long: string[];
  medium: string[];
  basic: string[];
  short: string[];
  pin: string[];
  name: string[];
  phrase: string[];
}

export interface MPWPassChars {
  V: string; // 大写元音
  C: string; // 大写辅音
  v: string; // 小写元音
  c: string; // 小写辅音
  A: string; // 大写字母
  a: string; // 所有字母
  n: string; // 数字
  o: string; // 符号
  x: string; // 所有字符
  ' ': string; // 空格
}

export interface ScryptParams {
  N: number; // CPU/memory cost parameter
  r: number; // block size parameter
  p: number; // parallelization parameter
  keyLen: number; // derived key length
}

export interface PBKDF2Params {
  iterations: number;
  keyLen: number;
  hash: HashAlgorithm;
}

// 加密函数类型
export type ScryptFunction = (
  password: Uint8Array,
  salt: Uint8Array,
  N: number,
  r: number,
  p: number,
  keyLen: number
) => Promise<Uint8Array>;

export type PBKDF2Function = (
  password: Uint8Array,
  salt: Uint8Array,
  iterations: number,
  keyLen: number,
  hash: string
) => Promise<Uint8Array>;

// setImmediate polyfill 类型
export type SetImmediateFunction = (callback: () => void) => void;

// MPW 算法版本
export const MPW_VERSIONS = [0, 1, 2, 3] as const;
export type MPWVersion = typeof MPW_VERSIONS[number];

// MPW 命名空间
export interface MPWNamespaces {
  readonly NS: string;
  readonly AuthenticationNS: string;
  readonly IdentificationNS: string;
  readonly RecoveryNS: string;
  readonly PasswordNS: string; // 已弃用
  readonly LoginNS: string; // 已弃用
  readonly AnswerNS: string; // 已弃用
}

// MPW 实例接口
export interface IMPWInstance {
  readonly name: string;
  readonly version: MPWVersion;
  readonly key: Promise<CryptoKey | Uint8Array>;

  // 主要生成方法
  generate(
    site: string,
    counter?: number,
    context?: string | null,
    template?: PasswordTemplate,
    NS?: string
  ): Promise<string>;

  // 特定用途的生成方法
  generateAuthentication(
    site: string,
    counter?: number,
    context?: string,
    template?: PasswordTemplate
  ): Promise<string>;

  generateIdentification(
    site: string,
    counter?: number,
    context?: string,
    template?: PasswordTemplate
  ): Promise<string>;

  generateRecovery(
    site: string,
    counter?: number,
    context?: string,
    template?: PasswordTemplate
  ): Promise<string>;

  // 已弃用的方法（保持向后兼容）
  generatePassword(
    site: string,
    counter?: number,
    template?: PasswordTemplate
  ): Promise<string>;

  generateLogin(
    site: string,
    counter?: number,
    template?: PasswordTemplate
  ): Promise<string>;

  generateAnswer(
    site: string,
    counter?: number,
    context?: string,
    template?: PasswordTemplate
  ): Promise<string>;

  // 种子计算
  calculateSeed(
    site: string,
    counter?: number,
    context?: string | null,
    NS?: string
  ): Promise<Uint8Array>;

  // 实例管理
  invalidate(): void;
}

// MPW 类静态接口
export interface IMPWStatic {
  new (name: string, password: string, version?: MPWVersion): IMPWInstance;

  // 静态属性
  readonly VERSION: MPWVersion;
  readonly txtencoder: TextEncoder;
  readonly templates: MPWTemplates;
  readonly passchars: MPWPassChars;
  readonly namespaces: MPWNamespaces;

  // 静态方法
  calculateKey(
    name: string,
    password: string,
    version?: MPWVersion
  ): Promise<CryptoKey | Uint8Array>;

  test(): Promise<void>;

  // 工具方法
  isValidTemplate(template: string): template is PasswordTemplate;
  isValidVersion(version: number): version is MPWVersion;
  getTemplateNames(): PasswordTemplate[];
}

// 错误类型
export class MPWError extends Error {
  public readonly code?: string;

  constructor(message: string, code?: string) {
    super(message);
    this.name = 'MPWError';
    this.code = code;
  }
}

export class MPWValidationError extends MPWError {
  public readonly field: string;

  constructor(message: string, field: string) {
    super(message, 'VALIDATION_ERROR');
    this.name = 'MPWValidationError';
    this.field = field;
  }
}

export class MPWAlgorithmError extends MPWError {
  public readonly version?: MPWVersion;

  constructor(message: string, version?: MPWVersion) {
    super(message, 'ALGORITHM_ERROR');
    this.name = 'MPWAlgorithmError';
    this.version = version;
  }
}

// 全局声明扩展
declare global {
  interface Window {
    scrypt?: ScryptFunction;
    pbkdf2?: PBKDF2Function;
    setImmediate?: SetImmediateFunction;
    CryptoJS?: any; // crypto-js 库的类型（如果使用）
  }
}
